library(rgeos)
# Bike data
bikes_tbl      <- readRDS("bikes_tbl.rds")
bikeshops_tbl  <- readRDS("bikeshops_tbl.rds")
orderlines_tbl <- readRDS("orderlines_tbl.rds")

bike_orderlines_tbl <- orderlines_tbl %>%
    left_join(bikes_tbl,     by = c("product_id" = "bike_id")) %>%
    left_join(bikeshops_tbl, by = c("customer_id" = "bikeshop_id")) %>%
    mutate(total_price = price_euro * quantity)


# German spatial data
germany_sp <- getData('GADM', country='DE', level=1) 
germany_sf <- st_as_sf(germany_sp) %>% 
  
                  # Add english names
                  mutate(VARNAME_1 = ifelse(is.na(VARNAME_1), NAME_1, VARNAME_1)) 

Column

By State

geo_plot_tbl <- bike_orderlines_tbl %>% 
                  group_by(state) %>%
                  summarise(total_revenue = sum(total_price)) %>%
                  ungroup() %>%
                  right_join(germany_sf, by = c("state" = "VARNAME_1")) %>% 
                  mutate(total_revenue = ifelse(is.na(total_revenue), 0, total_revenue)) %>% 
                  mutate(label_text = str_glue("State: {state}
                                         Revenue: {format_to_euro(total_revenue)}")) %>% 
                  st_as_sf()
## `summarise()` ungrouping output (override with `.groups` argument)
plot_ly(geo_plot_tbl, 
        split      = ~NAME_1, 
        color      = ~total_revenue,
        colors     = "Blues",
        stroke     = I("black"),
        hoverinfo  = 'text', 
        text       = ~label_text, 
        hoveron    = "fills", 
        showlegend = FALSE) 
## Warning: `group_by_()` is deprecated as of dplyr 0.7.0.
## Please use `group_by()` instead.
## See vignette('programming') for more help
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
## No trace type specified:
##   Based on info supplied, a 'scatter' trace seems appropriate.
##   Read more about this trace type -> https://plot.ly/r/reference/#scatter
## Warning: `arrange_()` is deprecated as of dplyr 0.7.0.
## Please use `arrange()` instead.
## See vignette('programming') for more help
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.